package javabase.proxy;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class ProxyTest {
	
	
	public static void main(String[] args) {
		Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		
		System.out.println(clazz.getName());
		
		Constructor[] constructors = clazz.getConstructors();
		
		for(Constructor constructor : constructors) {
			StringBuilder sb = new StringBuilder(constructor.getName());
			Class[] paramTypes = constructor.getParameterTypes();

			sb.append('(');
			for(Class paramType : paramTypes) {
				sb.append(paramType.getTypeName());
			}
			
			sb.append(')');
			System.out.println(sb.toString());
		}
		

		Method[] methods = clazz.getMethods();
		
		for(Method method : methods) {
			Class[] paramTypes = method.getParameterTypes();
			StringBuilder sb = new StringBuilder(method.getName());
			sb.append('(');
			for(Class paramType : paramTypes) {
				sb.append(paramType.getTypeName() + ", ");
			}
			sb.append(')');
			System.out.println(sb.toString());
		}
		
		
		try {
			Constructor constructor = clazz.getConstructor(InvocationHandler.class);
			
			class MyInvocationHandler1 implements InvocationHandler{

				@Override
				public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
					// TODO Auto-generated method stub
					return null;
				}
				
			}
			
			Collection collection = (Collection) constructor.newInstance(new MyInvocationHandler1());
			
//			System.out.println(collection.isEmpty());
			
			
			Collection collection2 = (Collection) Proxy.newProxyInstance(Collection.class.getClassLoader()
					, new Class[] {Collection.class }, new InvocationHandler() {
						
						Collection list = new ArrayList();
				
						@Override
						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							// TODO Auto-generated method stub
							System.out.println(method.getName());
							return method.invoke(list, args);
						}
					});
			
			collection2.add(1);
			collection2.add("222");
			System.out.println(collection2.size());
			
		} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		
	}
	
}
